#include <QtGui/QApplication>
#include "mainwindow.h"
#include "../../GraphHandler.hpp"
#include "SingleGraphClusterer.hpp"
#include "../../AlgorithmStats.hpp"

void GenerateRandomGraphs(MainWindow& w)
{
    std::vector< std::string > kNames;
    std::vector< std::vector<double> > dMap;

    kNames.resize(4);

    kNames[0] = "A";
    kNames[1] = "B";
    kNames[2] = "C";
    kNames[3] = "D";



    for( int i=0; i<kNames.size(); i++ )
    {
        dMap.push_back( std::vector<double> () );
        dMap[dMap.size()-1].resize(kNames.size(), 0.0);
    }

    dMap[0][1] = 0.3;
    dMap[3][2] = 0.7;
    dMap[0][3] = 0.1; // Noise
    dMap[2][1] = 0.1;
    cout << "Entering random gen" << endl;
    //for( int i=0; i<10; i++ )
    int i = 0;
    int iTo = 30;
// "/mlclustering/ml_modularity
   // system ("./mlclustering/ml_modularity graphname.edges.gz configname outname");
    while( i < iTo )
    {
        cout << i << endl;
        GraphHandler::Graph* G = &w.NewGraph();
        w.GenerateRandomGraph(*G, kNames, dMap);
        //w.m_OwnGraphs.push_back(G);

        if( i == iTo - 1 )
        {
            //GraphHandler::Instance().RemoveDuplicates(&w.m_OwnGraphs);
        }
        i = w.m_OwnGraphs.size();
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    int iLoad = 9999;

/*
    int iLoaded = GraphHandler::Instance().LoadAllGraphs("corpus/", iLoad);

    GraphHandler::Instance().RemoveIsolatedVertices();
    GraphHandler::Instance().RemoveDuplicates();
    GraphHandler::Instance().LoadBlacklist("blacklist");

    w.m_Clusters = GraphHandler::Instance().StructureClustering2();
    GraphHandler::Instance().Save("blacklistdata3");*/
//data4
    GraphHandler::Instance().Load("data99");
    /*
    GraphHandler::Instance().FilterTransformMetaGraph(60,0);
    GraphHandler::Instance().StructureClustering3(0.03);
    */
    cout << "Graphs: " << GraphHandler::Instance().GetTotalNumGraphs() << endl;
    cout << "Vertices: " << GraphHandler::Instance().GetTotalNumVertices() << endl;
    cout << "Edges: " << GraphHandler::Instance().GetTotalNumEdges() << endl;
    cout << "Types: " << GraphHandler::Instance().GetTotalNumLabels() << endl;


    //GraphHandler::Instance().AssertUniqueLabels();
    //GraphHandler::Instance().RemoveDisconnectedGraphs();
    GraphHandler::Instance().Save("data99");
    TestingSet kSet;
    AlgorithmStats test;


    vector<int> sizes;
    int iStart = 1;
    for(int i=0; i < iStart; i++)
        sizes.push_back(0);

    for(int i=iStart; i < 26; i++)
        sizes.push_back(50);

    //kSet = test.GenerateTestingSet(sizes);
    //kSet.Save("TestSetSmall");

    //GenerateFrequentEditMaps

    kSet.Load("TestSetSmall");
    cout << "Correct predictions (non-brute force): " << test.TestAll(kSet, false, "tmp.txt") << endl;
    vector<int> iFailedNBF = kSet.iFailedIDs;
    vector<int> iSuccNBF = kSet.iSuccIDs;
    //cout << "Correct predictions (brute force): " << test.TestAll(kSet, true, "tmp.txt") << endl;

    // See which NBF succeeded while BF failed
    vector<int> v;
    v.resize(999);
    sort(iFailedNBF.begin(), iFailedNBF.end());
    sort(kSet.iSuccIDs.begin(), kSet.iSuccIDs.end());
    vector<int>::iterator it = set_intersection (iFailedNBF.begin(), iFailedNBF.end(), kSet.iSuccIDs.begin(), kSet.iSuccIDs.end(), v.begin());

/*
    cout << "FailedNBF:" << endl;
    for(int i=0; i < iFailedNBF.size(); i++)
        cout << iFailedNBF[i] << endl;

    cout << "iSuccIDs:" << endl;
    for(int i=0; i < kSet.iSuccIDs.size(); i++)
        cout << kSet.iSuccIDs[i] << endl;*/


    cout << "iSuccNBF:" << iSuccNBF.size() << endl;
    cout << "iSuccIDs:" << kSet.iSuccIDs.size() << endl;


    //GraphHandler::Instance().Load("blacklistdata3");
    /*
    GraphHandler::Instance().SaveBlacklist("blacklist", 30);
    GraphHandler::Instance().BlacklistOnCriterion(30);*/

    w.PopulateGraphTree();
    w.show();


    w.SetGraphNumber(GraphHandler::Instance().GenerateTestExample());

    cout << "v.size: " << int(it - v.begin()) << endl;
    if( int(it - v.begin()) > 0 )
    {
    //Graph* m_pEGraph;
    //Graph m_kPartialG;

        GraphHandler::Instance().m_pEGraph = &GraphHandler::Instance().GetGraph(kSet.GetPGData(v[0]).first);
        GraphHandler::Instance().m_kPartialG = kSet.GetPGData(v[0]).second;

        cout << "Intersection: " << endl;
        vector< pair<unsigned int, GraphHandler::Graph> > pgs;
        for(int i=0; i < int(it - v.begin()); i++)
        {
            cout << v[i] << endl;
            pgs.push_back(kSet.GetPGData(v[i]));
        }
        w.AddPartialGraphs(pgs);
    }

    w.DisplayGraph(*GraphHandler::Instance().m_pEGraph,&GraphHandler::Instance().m_kPartialG);



    return a.exec();
}
